home *** CD-ROM | disk | FTP | other *** search
- procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
-
- {This is the flash display routine used to display crunched TheDraw image
- files. It uses a custom protocol for reproducing a image with any
- possible color combinations. The control codes below #32 are reserved
- for this function. The following data structure shows the format of a
- sequence. Not all operations use the optional bytes <x> or <y>..
-
- Data Structure: <current byte>[<x>[<y>]]
-
- 0..15 = New Foreground Color
- 16..23 = New Background Color
- 24 = Go down to next line, return to same horizontal position as when
- routine was started (akin to a c/r).
- 25 = Displays <x> number of spaces.
- 26 = Displays <x> number of <y>. Also used to display ANY characters
- below #32. This function is the only way to do this although it
- uses three bytes. Otherwise the code would be interpreted as
- another command.
-
- ----------------------------------------------------------------------------
-
- To use this routine you call the procedure with the ImageData as the
- first parameter, the display address as the second parameter, and the
- length of the ImageData as the third parameter.
-
- Assume we have a ImageData file of a 40 characters by 10 lines block. Also
- the following defintions. ie:
-
- type ScreenType = array [0..3999] of Byte;
- var ScreenAddr : ScreenType absolute $B800:$0000;
-
- const ImageData : array [1..467] of Byte =
- (...list of image bytes here...);
-
- begin
- UnCrunch (ImageData,ScreenAddr[ (34*2) + (5*160) -162],467);
- end;
-
-
- SCREENADDR is a variable mapped to the same location as the physical video
- addresses (using Turbo's absolute addressing). The fairly complex array
- address in the call tells UnCrunch where to start displaying the ImageData
- 40 character by 10 line block. The 34*2 indicates the horizontal position
- number 34 with the 5*160 indicating line number 5. This is similar to a
- Turbo GOTOXY (34,5) statement, except it works for UnCrunch instead.
-
- The value of 467 used in the call is the length of the array as indicated
- in the CONST statement.
-
- UnCrunch remembers the horizontal (X) starting position when it goes down
- to the next line. This allows you to display the ImageData block correctly
- at any position on the screen. ie:
-
- +-------------------------------------------------+
- | |
- | | <- Pretend this
- | | is the video
- | ┌─────────────────────┐ | display.
- | │█████████████████████│ |
- | │█████████████████████│ |
- | │██ ImageData block ██│ |
- | │█████████████████████│ |
- | │█████████████████████│ |
- | │█████████████████████│ |
- | └─────────────────────┘ |
- | |
- | |
- | |
- +-------------------------------------------------+
-
-
- The ImageData block could just as well have been display in the upper-left
- corner of the screen with:
- UNCRUNCH (ImageData,ScreenAddr[ (1*2) + (1*160) -162],467);
-
- Notice the array address changed to the equivilant of GOTOXY (1,1);
-
- To display the block in the lower-right corner you would use:
- UNCRUNCH (ImageData,ScreenAddr[ (40*2) + (15*160) -162],467);
-
- The block is 40 characters wide by 10 lines deep. Therefore to display
- such a large block, we must display the block at GOTOXY (40,15);
-
-
-
- Obviously I have been attempting to describe this procedure by use of
- examples. This is done because I feel it is the easiest and clearest way
- of explaining this procedure. It was designed to be as simple as possible,
- however for some people the best way to learn it is to experiment. Try
- creating a program using the above example information. Use TheDraw to
- make a 40 by 10 block (or any size) to experiment with. Good luck. If
- you can devise a better way of explaining this, please share your labors
- with me. Others will surely benifit. Thanks!
-
- }
- begin
- inline (
- $1E/ { PUSH DS}
- $C5/$B6/Addr1/ { LDS SI,[BP+Addr1] ;Source Address}
- $C4/$BE/Addr2/ { LES DI,[BP+Addr2] ;Destination Addr}
- $8B/$8E/BlkLen/ { MOV CX,[BP+BlkLen] ;Length of block}
- $8B/$D7/ { MOV DX,DI ;Save X coord for later.}
- $B4/$00/ { MOV AH,0 ;Current attributes.}
- $AC/ {LOOPA: LODSB ;Get next character.}
- $3C/$10/ { CMP AL,16 ;If less than 16,}
- $73/$07/ { JNC Short BackG ;then change the}
- $80/$E4/$F0/ { AND AH,0F0H ;foreground color.}
- $0A/$E0/ { OR AH,AL}
- $EB/$44/ { JMP Short Next}
- $3C/$18/ {BackG: CMP AL,24 ;If less than 24,}
- $74/$13/ { JZ Short NextL ;then change the}
- $73/$19/ { JNC Short Multi ;background color.}
- $2C/$10/ { SUB AL,16}
- $02/$C0/ { ADD AL,AL}
- $02/$C0/ { ADD AL,AL}
- $02/$C0/ { ADD AL,AL}
- $02/$C0/ { ADD AL,AL}
- $80/$E4/$0F/ { AND AH,0FH}
- $0A/$E0/ { OR AH,AL}
- $EB/$2D/ { JMP Short Next}
- $81/$C2/$A0/$00/ {NextL: ADD DX,160 ;If equal to 24,}
- $8B/$FA/ { MOV DI,DX ;then jump down to}
- $EB/$25/ { JMP Short Next ;the next line.}
- $3C/$1A/ {Multi: CMP AL,26 ;If equal to 26,}
- $75/$0B/ { JNZ Space ;then using the}
- $AC/ { LODSB ;following two codes}
- $49/ { DEC CX ;Adjust main counter.}
- $51/ { PUSH CX ;display as many of}
- $32/$ED/ { XOR CH,CH ;whatever the user}
- $8A/$C8/ { MOV CL,AL ;wants.}
- $AC/ { LODSB ;Get character.}
- $EB/$0D/$90/ { JMP Start ;Use below loop.}
- $3C/$19/ {Space: CMP AL,25 ;If equal to 25,}
- $75/$11/ { JNZ Short Lettr ;then using the}
- $AC/ { LODSB ;following code as}
- $51/ { PUSH CX ;a count, output}
- $32/$ED/ { XOR CH,CH ;said number of}
- $8A/$C8/ { MOV CL,AL ;spaces.}
- $B0/$20/ { MOV AL,32}
- $0B/$C9/ {Start: OR CX,CX ;Abort if already}
- $74/$03/ { JZ Stop ;at zilch.}
- $AB/ {LOOPB: STOSW}
- $E2/$FD/ { LOOP LOOPB}
- $59/ {Stop: POP CX}
- $49/ { DEC CX ;Adjust main counter.}
- $AB/ {Lettr: STOSW ;Save screen letter.}
- $0B/$C9/ {Next: OR CX,CX ;Get next, unless}
- $74/$02/ { JZ Done ;CX has already}
- $E2/$AA/ { LOOP LOOPA ;gone to zero.}
- $1F); {Done: POP DS}
- end; {UNCRUNCH}